#ifndef __DCMOTOR_H__
#define __DCMOTOR_H__

#include "soc/soc_gpio.h"
#include "plat/nonecopyable.h"
#include "device_def.h"
#include "os/timer.h"
#include "softupdatepwm.h"
#include "lib/controlacc.h"

#define DCMOTOR_TIMER_TICK_MS 20

/// @brief 直流电机
class DcMotor : public NoneCopyable
{
public:
    explicit DcMotor();
    explicit DcMotor(const GpioPortPin &backPortPin, const GpioPortPin &frontPortPin);
    virtual ~DcMotor();

public:
    void Config(const GpioPortPin &backPortPin, const GpioPortPin &frontPortPin);
    void AttachPwm(SoftUpdatePwm *pwm, int duty0 = 100, int dutyMax = 100, int speedUs = 0);
    void DettachPwm();

    DeviceDirection GetCurrentDirection();
    bool IsRunning();
    void Start(DeviceDirection dir);
    void ReStart(DeviceDirection dir);
    void StartTime(DeviceDirection dir, int ms);
    /// @brief 累加模式，多次调用，多次累加ms, 并且自动换向
    /// @param dir 
    /// @param ms 
    void StartTimeWithSumAndAutoDir(DeviceDirection dir, int ms);
    void Stop();

    int GetRunningTimeMs();

private:
    void StartImpl(DeviceDirection dir, int ms = -1);
    void StartTimer();
    void TimerHandler();
    void Control(DeviceDirection dir);
    void ControlImpl(const GpioPortPin &pwmPortPin, const GpioPortPin &lowPortPin);

private:
    SoftUpdatePwm *m_pwm = nullptr;
    GpioPortPin m_backPort;
    GpioPortPin m_frontPort;
    int m_remainsRunTime = 0;
    
    bool m_isRunning = false;
    DeviceDirection m_currentDir = DeviceDirection::None;
    ControlAcc m_accer;

    Timer m_timer;
    //最后一次运行的时间
    int m_runningMs = 0;
};

#endif // __DCMOTOR_H__
